import 'dart:io';

import 'package:file_cache/src/file_utils.dart';
import 'package:flutter/foundation.dart';

final FileCacheManager fileCacheManager = FileCacheManager();

// 不支持并发改同一文件，抛出异常
class FileCacheManager {
  FileCacheManager._internal();

  factory FileCacheManager() => _instance;

  static final FileCacheManager _instance = FileCacheManager._internal();

  final Map<String, bool> _isFileOperating = {};

  Future<void> putCache(
    String key,
    String json, {
    Map<String, dynamic> params = const {},
  }) async {
    Uri uri = Uri(
        host: "file_cache",
        path: key,
        queryParameters: params.map((key, value) => MapEntry(key, value.toString())));
    String realKey = uri.toString();
    if (true == _isFileOperating[realKey]) {
      throw StateError("concurrent modify file: ${uri.toString()}");
    }
    try {
      _isFileOperating[realKey] = true;
      String targetFilePath = await FileCacheUtils.getTargetFilePath(realKey);
      File file = File(targetFilePath);
      bool exist = await file.exists();
      if (exist) {
        file.writeAsStringSync(json);
      } else {
        // recursive = true: 父文件不存在也递归创建父文件目录
        // 同步操作
        file.createSync(recursive: true);
        file.writeAsStringSync(json);
      }
      _isFileOperating.remove(realKey);
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  // file not find return empty str
  Future<String> getCache(String key, {Map<String, dynamic> params = const {}}) async {
    Uri uri = Uri(
        host: "file_cache",
        path: key,
        queryParameters: params.map((key, value) => MapEntry(key, value.toString())));
    String realKey = uri.toString();
    String targetFilePath = await FileCacheUtils.getTargetFilePath(realKey);
    File file = File(targetFilePath);
    bool exist = await file.exists();
    if (exist) {
      return file.readAsStringSync();
    } else {
      return "";
    }
  }
}
